/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bff.designtime.generator.core.rtgen.managergenerator.mgrImplclass.methodgenerators.getchangeconvertormethod;

import com.inspur.edp.bff.designtime.generator.core.rtgen.managergenerator.mgrImplclass.FSMgrImplGenContext;
import com.inspur.edp.bff.spi.changeset.AbstractBffChangeJsonDeserializer;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.utils.ExpressionUtils;
import lombok.var;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;

import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

public class GetChangeDeSerGenerator extends ClassMethodGenerator{

    private FSMgrImplGenContext mgrContext;

    public final FSMgrImplGenContext getMgrContext() {
        return mgrContext;
    }

    public GetChangeDeSerGenerator(FSMgrImplGenContext context) {
        mgrContext = context;
    }

    @Override
    protected String getMethodName() {
        return "getChangeDeserializer";
    }


    @Override
    protected TypeInfo getReturnType() {
        return new TypeInfo(AbstractBffChangeJsonDeserializer.class);
    }

    @Override
    protected ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
        return new ArrayList<Modifier.ModifierKeyword>(Arrays.asList(new Modifier.ModifierKeyword[]
                {
                        Modifier.ModifierKeyword.PROTECTED_KEYWORD
                }));
    }

    @Override
    protected ArrayList<ParameterInfo> getParameterCollection() {
        return null;
    }

    @Override
    protected Block buildMethodBody() {
        Block block = ast.newBlock();
        block.statements().add(buildFsManager());
        block.statements().add(buildChangeDeserConvertor());
        return block;
//        var returnStatement = ast.newReturnStatement();
//        var creation = ast.newClassInstanceCreation();
//        creation.setType(ast.newSimpleType(ast.newSimpleName(
//            getMgrContext().getMgrGenContext().getChangeSerContext().getDeserializerClassName())));
//        returnStatement.setExpression(creation);
//
//        var block = ast.newBlock();
//        block.statements().add(returnStatement);
//
 //       return block;
    }

    private final String convertType = "com.inspur.edp.bff.spi.BffChangeDeserConvertor";
    private String ifsManagerVariableName = "ifsManager";

    private ReturnStatement buildChangeDeserConvertor() {
        ReturnStatement returnStatement = ast.newReturnStatement();
        ClassInstanceCreation instanceCreation = ast.newClassInstanceCreation();
        instanceCreation.setType(ast.newSimpleType(ast.newName(convertType)));
        buildSerializerArguments(instanceCreation);
        returnStatement.setExpression(instanceCreation);
        return  returnStatement;
    }

    private void buildSerializerArguments(ClassInstanceCreation instanceCreation) {
        instanceCreation.arguments().add(ExpressionUtils.getStringLiteral(ast, getNodeCode()));
        instanceCreation.arguments().add(ast.newBooleanLiteral(isRoot()));
        instanceCreation.arguments().add(ExpressionUtils.getStringLiteral(ast, getConfigId()));
        MethodInvocation cefResInfo = ast.newMethodInvocation();
        cefResInfo.setName(ast.newSimpleName(getCefResourceInfoMethodName()));
        cefResInfo.arguments().add(ast.newSimpleName(ifsManagerVariableName));
        cefResInfo.arguments().add(ExpressionUtils.getStringLiteral(ast, getNodeCode()));
        instanceCreation.arguments().add(cefResInfo);
    }

    private VariableDeclarationStatement buildFsManager() {
        VariableDeclarationFragment ifsManagerName = ast.newVariableDeclarationFragment();
        ifsManagerName.setName(ast.newSimpleName(ifsManagerVariableName));
        ClassInstanceCreation newManagerClass =  ast.newClassInstanceCreation();
        newManagerClass.setType(ast.newSimpleType(ast.newName(mgrContext.getMgrImplType().getFullName())));
        VariableDeclarationStatement fsManager = ast.newVariableDeclarationStatement(ifsManagerName);
        fsManager.setType(ast.newSimpleType(ast.newSimpleName("IFSManager")));
        ifsManagerName.setInitializer(newManagerClass);
        return fsManager;
    }

    private String getNodeCode() {
        return mgrContext.getMgrGenContext().getFSGeneratorContext().getVmGenContext().getCommonDataType().getCode();
    }

    private String getCefResourceInfoMethodName() {
        return "cefEntityResInfo";
    }

    private boolean isRoot() {
        String nowNodeCode = getNodeCode();
        String rootNodeCode = mgrContext.getMgrGenContext().getFSGeneratorContext().getVmGenContext().getRootNodeCode();
        return nowNodeCode.equalsIgnoreCase(rootNodeCode);
    }

    private String getConfigId() {
        return mgrContext.getMgrGenContext().getProjContext().getConfig().getID();
    }
}
